package map_data_init

import (
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/game_core"
	"go_server/zinx/zlog"
	"math"
)

const (
	InitMapID   = 2
	InitBlockID = 1
)

var (
	totalMaps       = make(map[int32]*game_core.Map)
	InitBuildPosMap = make(map[int32]map[uint8][]buildInitPos)
	LockedBuildPosMap = make(map[int32]map[uint8][]buildInitPos)
)

type buildInitPos struct {
	InitPosX int32
	InitPosZ int32
	Id       int32
	Level    int32
	CfgKey   int32
	ClickType int32
}

func InitMapGridData() {
	mapMaps := config_manager.GetTableMap3DConfigSheetMapMap()
	for mapId, info := range mapMaps {
		xBlockNum := info.BlockNum[0]
		zBlockNum := info.BlockNum[2]
		xUnitGridNum := info.BlockUnitGridNum[0]
		zUnitGridNum := info.BlockUnitGridNum[2]
		xCount := (info.BlockSpacing[0]+xUnitGridNum)*xBlockNum + info.BlockSpacing[0]
		zCount := (info.BlockSpacing[2]+zUnitGridNum)*zBlockNum + info.BlockSpacing[2]

		zPerUnit, _ := GetMapAvgData(zCount)
		xPerUnit, xUnitCount := GetMapAvgData(xCount)
		indexMap := game_core.NewMap(xCount * zCount, xCount, zCount)

		for i := int32(0); i < zCount; i++ {
			zArray := i / zPerUnit
			for j := int32(0); j < xCount; j++ {
				xArray := j / xPerUnit
				grid := game_core.NewGrid(j, i, uint8(zArray*xUnitCount+xArray))
				indexMap.GridMap[grid.Key] = grid
			}
		}

		totalMaps[mapId] = indexMap
	}

	wallMap := config_manager.GetTableMap3DConfigSheetWallMap()
	for _, info := range wallMap {
		xCount := info.GridNum[0]
		zCount := info.GridNum[2]
		startX := info.RelativeBlockIdx[0]
		startZ := info.RelativeBlockIdx[2]

		indexMap, ok := totalMaps[info.MapId]
		if !ok {
			zlog.Panicf("InitMapGridData err !!! 找不到格子对应的地图ID, mapId: %d", info.MapId)
		}

		for i := int32(0); i < zCount; i++ {
			for j := int32(0); j < xCount; j++ {
				indexMap.SetGridStatusByKey(startX+j, startZ+i, true)
			}
		}
	}

	initBuildArray := config_manager.GetBuildConfigByBlockID(InitBlockID)
	areaMaps := make(map[uint8][]buildInitPos)
	for _, config := range initBuildArray {
		initPosx := config.MapPos[0]
		initPosz := config.MapPos[2]
		buildConfig, ok := config_manager.GetTableBuildSheetBuildConfig(config.BuildId)
		if !ok {
			continue
		}
		buildWidth := buildConfig.GridNum[0]
		buildHeight := buildConfig.GridNum[0]

		grid, ok := totalMaps[InitMapID].GetGridByKey(initPosx, initPosz)
		if !ok {
			continue
		}

		areaId := grid.Index
		clickType := int32(-1)
		if config.ClickType[0] == 0 {
			clickType = config.ClickType[1]
		}

		areaMaps[areaId] = append(areaMaps[areaId], buildInitPos{
			InitPosX: initPosx,
			InitPosZ: initPosz,
			Id:       config.BuildId,
			Level:    config.BuildLv,
			CfgKey: config.Id,
			ClickType: clickType,
		})

		for i := int32(0); i < buildHeight; i++ {
			for j := int32(0); j < buildWidth; j++ {
				totalMaps[InitMapID].SetGridStatusByKey(initPosx+j, initPosz+i, true)
			}
		}
	}
	InitBuildPosMap[InitMapID] = areaMaps

	config := config_manager.GetTableMap3DConfigSheetBlockConfig(InitBlockID)
	if config.NextBlockId > 0 {
		nextBuildArray := config_manager.GetBuildConfigByBlockID(config.NextBlockId)
		lockedAreaMaps := make(map[uint8][]buildInitPos)
		for _, lockedConfig := range nextBuildArray {
			initPosx := lockedConfig.MapPos[0]
			initPosz := lockedConfig.MapPos[2]
			buildConfig, ok := config_manager.GetTableBuildSheetBuildConfig(lockedConfig.BuildId)
			if !ok {
				continue
			}
			buildWidth := buildConfig.GridNum[0]
			buildHeight := buildConfig.GridNum[0]

			grid, ok := totalMaps[InitMapID].GetGridByKey(initPosx, initPosz)
			if !ok {
				continue
			}

			areaId := grid.Index
			clickType := int32(-1)
			if lockedConfig.ClickType[0] == 0 {
				clickType = lockedConfig.ClickType[1]
			}

			lockedAreaMaps[areaId] = append(lockedAreaMaps[areaId], buildInitPos{
				InitPosX: initPosx,
				InitPosZ: initPosz,
				Id:       lockedConfig.BuildId,
				Level:    lockedConfig.BuildLv,
				CfgKey: lockedConfig.Id,
				ClickType: clickType,
			})

			for i := int32(0); i < buildHeight; i++ {
				for j := int32(0); j < buildWidth; j++ {
					totalMaps[InitMapID].SetGridStatusByKey(initPosx+j, initPosz+i, true)
				}
			}
		}
		LockedBuildPosMap[InitMapID] = lockedAreaMaps
	}
}

func GetTotalMap() map[int32]*game_core.Map {
	return totalMaps
}

func GetMapAvgData(count int32) (perUnitGrids int32, unitCount int32) {
	tempCount := 0
	for {
		if count%2 == 0 {
			count = count / 2
			tempCount++
		} else {
			perUnitGrids = count
			unitCount = int32(math.Pow(2, float64(tempCount)))
			return
		}
	}
}
